package com.ruoyi.eduManage.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.eduManage.mapper.SysMailConfigMapper;
import com.ruoyi.eduManage.domain.SysMailConfig;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * 邮件发送工具类
 *
 * @author ruoyi
 */
@Component
public class MailUtils {

    private static final Logger logger = LoggerFactory.getLogger(MailUtils.class);

    @Autowired(required = false)
    private JavaMailSender mailSender;

    @Autowired(required = false)
    private ISysDictDataService dictDataService;

    @Autowired(required = false)
    private TemplateEngine templateEngine;

    @Autowired(required = false)
    private SysMailConfigMapper sysMailConfigMapper;


    /**
     * 获取邮件配置信息
     *
     * @param flag true-只查询备注为1的数据，false-查询全部数据
     * @return 邮件配置Map，key为字典键值，value为字典标签
     */
    public Map<String, String> getMailConfig(Boolean flag) {
        Map<String, String> configMap = new HashMap<>();
        // 优先通过sys_mail_config表的已激活配置获取
        try {
            SysMailConfig active = sysMailConfigMapper.selectActiveConfig();
            if (active != null) {
                configMap.put("mail.smtp.host", active.getSmtpHost());
                configMap.put("mail.smtp.port", active.getSmtpPort() == null ? null : String.valueOf(active.getSmtpPort()));
                configMap.put("mail.sendFrom", active.getSendFrom());
                configMap.put("mail.sendUserName", active.getSendUsername());
                configMap.put("mail.sendVerifyCode", active.getSendVerifyCode());
                return configMap;
            }
        } catch (Exception e) {
            logger.error("从sys_mail_config获取激活邮件配置失败: {}", e.getMessage());
        }

        /*// 兼容旧逻辑：若数据库未找到激活配置，回退到数据字典
        if (dictDataService != null) {
            try {
                List<SysDictData> configList = dictDataService.selectMailConfig(flag);
                for (SysDictData config : configList) {
                    configMap.put(config.getDictValue(), config.getDictLabel());
                }
            } catch (Exception e) {
                logger.error("从数据字典获取邮件配置失败: {}", e.getMessage());
            }
        }*/
        return configMap;
    }

    /**
     * 发送邮件（使用数据字典配置）
     *
     * @param to              收件人
     * @param subject         主题
     * @param content         内容
     * @param useActiveConfig 是否使用激活的配置（备注为1的配置）
     * @return 发送结果
     */
    public boolean sendMailWithConfig(String to, String subject, String content, boolean useActiveConfig) {
        Map<String, String> config = getMailConfig(useActiveConfig);
        if (config.isEmpty()) {
            logger.error("未找到邮件配置信息");
            return false;
        }

        try {
            // 从配置中获取邮件参数
            String host = config.get("mail.smtp.host");
            String port = config.get("mail.smtp.port");
            String username = config.get("mail.sendUserName");
            String password = config.get("mail.sendVerifyCode");
            String fromEmail = config.get("mail.sendFrom");

            if (host == null || port == null || username == null || password == null || fromEmail == null) {
                logger.error("邮件配置信息不完整");
                return false;
            }

            // 配置邮件属性
            Properties props = new Properties();
            props.put("mail.smtp.host", host);
            props.put("mail.smtp.port", port);
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.auth", "true");
            props.put("mail.mime.address.strict", "false");

            // 创建邮件会话
            Session session = Session.getInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

            // 创建并发送邮件
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
            message.setSubject(subject);
            message.setText(content);

            Transport.send(message);
            logger.info("邮件发送成功，收件人: {}", to);
            return true;
        } catch (Exception e) {
            logger.error("邮件发送失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 发送HTML邮件（使用数据字典配置）
     *
     * @param to              收件人
     * @param subject         主题
     * @param htmlContent     HTML内容
     * @param useActiveConfig 是否使用激活的配置（备注为1的配置）
     * @return 发送结果
     */
    public boolean sendHtmlMailWithConfig(String to, String subject, String htmlContent, boolean useActiveConfig) {
        Map<String, String> config = getMailConfig(useActiveConfig);
        if (config.isEmpty()) {
            logger.error("未找到邮件配置信息");
            return false;
        }

        try {
            // 从配置中获取邮件参数
            String host = config.get("mail.smtp.host");
            String port = config.get("mail.smtp.port");
            String username = config.get("mail.sendUserName");
            String password = config.get("mail.sendVerifyCode");
            String fromEmail = config.get("mail.sendFrom");

            if (host == null || port == null || username == null || password == null || fromEmail == null) {
                logger.error("邮件配置信息不完整");
                return false;
            }

            // 配置邮件属性
            Properties props = new Properties();
            props.put("mail.smtp.host", host);
            props.put("mail.smtp.port", port);
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.auth", "true");
            props.put("mail.mime.address.strict", "false");

            // 创建邮件会话
            Session session = Session.getInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

            // 创建并发送邮件
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
            message.setSubject(subject);
            message.setContent(htmlContent, "text/html; charset=utf-8");

            Transport.send(message);
            logger.info("HTML邮件发送成功，收件人: {}", to);
            return true;
        } catch (Exception e) {
            logger.error("HTML邮件发送失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 使用Thymeleaf模板发送邮件
     *
     * @param to              收件人
     * @param subject         主题
     * @param templateName    模板名称（不包含.html后缀）
     * @param variables       模板变量
     * @param useActiveConfig 是否使用激活的配置（备注为1的配置）
     * @return 发送结果
     */
    public boolean sendTemplateMailWithConfig(String to, String subject, String templateName,
                                              Map<String, Object> variables, boolean useActiveConfig) {
        if (templateEngine == null) {
            logger.error("TemplateEngine未初始化，无法发送模板邮件");
            return false;
        }

        try {
            // 创建Thymeleaf上下文
            Context context = new Context();
            if (variables != null) {
                context.setVariables(variables);
            }

            // 处理模板
            String htmlContent = templateEngine.process("mail/" + templateName, context);

            // 发送HTML邮件
            return sendHtmlMailWithConfig(to, subject, htmlContent, useActiveConfig);
        } catch (Exception e) {
            logger.error("模板邮件发送失败: {}", e.getMessage());
            return false;
        }
    }

    /** 邮件附件对象 */
    public static class Attachment {
        public String fileName;
        public String contentType;
        public byte[] data;
        public Attachment(String fileName, String contentType, byte[] data) {
            this.fileName = fileName;
            this.contentType = contentType;
            this.data = data;
        }
    }

    /**
     * 使用Thymeleaf模板发送带附件的邮件
     */
    public boolean sendTemplateMailWithConfig(String to, String subject, String templateName,
                                              Map<String, Object> variables, boolean useActiveConfig,
                                              List<Attachment> attachments) {
        if (templateEngine == null) {
            logger.error("TemplateEngine未初始化，无法发送模板邮件");
            return false;
        }
        Map<String, String> config = getMailConfig(useActiveConfig);
        if (config.isEmpty()) {
            logger.error("未找到邮件配置信息");
            return false;
        }
        try {
            // 模板渲染
            Context context = new Context();
            if (variables != null) {
                context.setVariables(variables);
            }
            String htmlContent = templateEngine.process("mail/" + templateName, context);

            // 邮件配置
            String host = config.get("mail.smtp.host");
            String port = config.get("mail.smtp.port");
            String username = config.get("mail.sendUserName");
            String password = config.get("mail.sendVerifyCode");
            String fromEmail = config.get("mail.sendFrom");
            if (host == null || port == null || username == null || password == null || fromEmail == null) {
                logger.error("邮件配置信息不完整");
                return false;
            }

            Properties props = new Properties();
            props.put("mail.smtp.host", host);
            props.put("mail.smtp.port", port);
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.auth", "true");
            props.put("mail.mime.address.strict", "false");

            Session session = Session.getInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
            message.setSubject(subject);

            javax.mail.internet.MimeMultipart multipart = new javax.mail.internet.MimeMultipart();
            // HTML正文
            javax.mail.internet.MimeBodyPart htmlPart = new javax.mail.internet.MimeBodyPart();
            htmlPart.setContent(htmlContent, "text/html; charset=utf-8");
            multipart.addBodyPart(htmlPart);

            // 附件
            if (attachments != null) {
                for (Attachment att : attachments) {
                    if (att == null || att.data == null) continue;
                    javax.mail.internet.MimeBodyPart attachPart = new javax.mail.internet.MimeBodyPart();
                    javax.activation.DataSource ds = new javax.mail.util.ByteArrayDataSource(att.data, att.contentType == null ? "application/octet-stream" : att.contentType);
                    attachPart.setDataHandler(new javax.activation.DataHandler(ds));
                    attachPart.setFileName(att.fileName == null ? "attachment" : att.fileName);
                    multipart.addBodyPart(attachPart);
                }
            }

            message.setContent(multipart);
            Transport.send(message);
            logger.info("模板邮件(含附件)发送成功，收件人: {}", to);
            return true;
        } catch (Exception e) {
            logger.error("模板邮件(含附件)发送失败: {}", e.getMessage());
            return false;
        }
    }


}